import xmlrpclib, string, xplib
from etoffiutils2.pkg import choose

from cStringIO import StringIO

class _Method:
	# some magic to bind an XML-RPC method to an RPC server.
	# supports "nested" methods (e.g. examples.getStateName)
	def __init__(self, send, name):
		self.__send = send
		self.__name = name
	def __getattr__(self, name):
		return _Method(self.__send, "%s.%s" % (self.__name, name))
	def __call__(self, *args):
		return self.__send(self.__name, args)

class ServerProxy:
	"""uri [,options] -> a logical connection to an XML-RPC server
	
	uri is the connection point on the server, given as
	scheme://host/target.
	
	The standard implementation always supports the "http" scheme.  If
	SSL socket support is available (Python 2.0), it also supports
	"https".
	
	If the target part and the slash preceding it are both omitted,
	"/RPC2" is assumed.
	
	The following options can be given as keyword arguments:
	
	transport: a transport factory
	encoding: the request encoding (default is UTF-8)
	
	All 8-bit strings passed to the server proxy are assumed to use
	the given encoding.
	"""
	
	def __init__(self, uri, transport=None, encoding=None, verbose=0):
		# establish a "logical" server connection
		
		# get the url
		x= string.split(uri,'/')
		assert x[0]==''
		assert x[1]=='svc'
		
		if x[2] != 'local': raise 'only local machine supported!'
		
		self.__paths = (x, uri)
		self.service = x[3]
		
		print 42,x
		
		self.__transport = choose(transport is None, Transport(),transport)
		
		self.__encoding = encoding
		self.__verbose = verbose
	
	def __request(self, methodname, params):
		# call a method on the remote server
		
		request = xmlrpclib.dumps(params, methodname, encoding=self.__encoding)
		
		response = self.__transport.request(
		    self.__host,
		    self.__handler,
		    request,
		    verbose=self.__verbose
		    )
		
		if len(response) == 1:
			response = response[0]
		
		return response
	
	def __repr__(self):
		return (
		    "<ServerProxy for %s%s>" %
		    (self.__host, self.__handler)
		    )
	
	__str__ = __repr__
	
	def gett(self, name):
		# magic method dispatcher
		return _Method(self.__request, name)
	
#	__getattr__=gett


def getConnector(l,transport):
	return ServerProxy(l,transport=transport)
	
class Foobar(object):
	def __init__(self, host):
#		print host
		pass
	def putrequest(self, method, handler):
		print  "putrequest", method, handler
	def putheader(self, name, value):
		print "putheader",name, value
	def endheaders(self):
		print "endheaders"
	def send(self, s):
		print "send",s
	def getfile(self):
		return open('w')
	def close(self):
		pass
	def getreply(self):
		return 200, 'hello', []
	def getresponse(self):
		class Resp: 
			def __init__(self):
				self.msg='pp'
				self.fp=StringIO(open('w'))
				self.status=200
				self.msg='fuck you'
				self.reason='because i said so'
		return Resp()

class xException(Exception): pass
	
class xx(xmlrpclib.Transport):
	"""Handles an HTTP transaction to an XML-RPC server."""
	
	# client identifier (may be overridden)
	#~ user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__
	
	def make_connection(self, host):
		# create a HTTP 1.1 connection object from a host descriptor
		# we want to reuse the same socket over and over
		R=xplib.HTTPConnection(host)
#		print 100,host
		#R=Foobar(host)
		return R
	
	def getreply(self, httpresp):
		"""Compat definition since superclass does not define it.
		
		Returns a tuple consisting of:
		- server status code (e.g. '200' if all goes well)
		- server "reason" corresponding to status code
		- any RFC822 headers in the response from the server
		"""
		try:
			response = httpresp.getresponse()
		except xException, e: #httplib.BadStatusLine, e:
			### hmm. if getresponse() ever closes the socket on a bad request,
			### then we are going to have problems with self.sock
	
			### should we keep this behavior? do people use it?
			# keep the socket open (as a file), and return it
			httpresp.file = httpresp.getfile() #_conn.sock.makefile('rb', 0)
	
			# close our socket -- we want to restart after any protocol error
			httpresp.close()
	
			httpresp.headers = None
			return -1, e.line, None
	
		httpresp.headers = response.msg
		httpresp.file = response.fp
		return response.status, response.reason, response.msg

	def p1arse_response(self, f):
		# read response from input file, and parse it
		
		p, u = self.getparser()
		
		while 1:
			response = f.read(1024)
			if not response:
				break
			if self.verbose:
				print "body:", repr(response)
			p.feed(response)
		
		f.close()
		p.close()
		
		return u.close()

	def r1equest(self, host, handler, request_body, verbose=0):
		# issue XML-RPC request
		
		try:
			h=self._h
		except AttributeError:
			h = self.make_connection(host)
			self._h =h
			if verbose:
				print '** new connection'
				h.set_debuglevel(1)
		
		self.send_request(h, handler, request_body)
		self.send_host(h, host)
		self.send_user_agent(h)
		self.send_content(h, request_body)
		
		errcode, errmsg, headers = self.getreply(h)
		
		#~ print 900,errcode, errmsg, headers, request_body
		
		if errcode != 200:
			raise xmlrpclib.ProtocolError(
				host + handler,
				errcode, errmsg,
				headers
				)
		
		self.verbose = verbose
		
		return self.parse_response(h.file)#getfile())

T=getConnector
Transport = xx

#
# eof
#
